package com.sayice.coursetable;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.GravityCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.sayice.coursetable.databinding.ActivityMainBinding;
import com.sayice.coursetable.databinding.BottomDialogBinding;
import com.sayice.coursetable.databinding.ClassImportDialogBinding;
import com.sayice.coursetable.databinding.ExamDialogBinding;
import com.sayice.coursetable.databinding.ScoreDialogBinding;
import com.sayice.coursetable.databinding.SettingDialogBinding;
import com.sayice.coursetable.databinding.TeacharImportDialogBinding;
import com.sayice.coursetable.databinding.UserSetDialogBinding;
import com.sayice.coursetable.databinding.UserinfoInputDialogBinding;
import com.sayice.coursetable.logic.Repository;
import com.sayice.coursetable.logic.dao.PreferencesDao;
import com.sayice.coursetable.logic.model.Exam;
import com.sayice.coursetable.logic.model.Score;
import com.sayice.coursetable.logic.utils.MusicUtils;
import com.sayice.coursetable.logic.worker.ExamMonitorWorker;
import com.sayice.coursetable.logic.worker.ScoreMonitorWorker;
import com.sayice.coursetable.ui.course.day.DayFragment;
import com.sayice.coursetable.ui.course.week.WeekFragment;
import com.sayice.coursetable.ui.exam.ExamAdapter;
import com.sayice.coursetable.ui.music.MusicFragment;
import com.sayice.coursetable.ui.score.ScoreAdapter;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;
    private MainViewModel viewModel;

    private final WeekFragment weekFragment = new WeekFragment();
    private final DayFragment dayFragment = new DayFragment();
    private final MusicFragment musicFragment = new MusicFragment();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("MainActivity", "onCreate");
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(binding.toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
        }

        viewModel = new ViewModelProvider(this).get(MainViewModel.class);
        viewModel.getTableName().observe(this, name ->
                binding.tableName.setText(name == null ? "课表" : name)
        );
        viewModel.getWeek().observe(this, week -> {
            Log.d("MainActivity", "weekChanged, tableId: " + viewModel.tableId);
            weekFragment.changeWeek(viewModel.tableId, week);
            binding.week.setText("第" + week + "周");
        });

        // 初始化
        setCourseView(PreferencesDao.isWeekView());
        updateCourseTable(false);

        // 设置侧边菜单 header 的点击事件
        View navHeaderView = binding.navView.getHeaderView(0);
        TextView nameText = navHeaderView.findViewById(R.id.username);
        String username = PreferencesDao.getUsername();
        nameText.setText(username == null ? "设置用户信息" : username);
        nameText.setOnClickListener(view -> {
            showUserSetDialog();
        });
        // 设置侧边菜单 menu 的点击事件
        binding.navView.setCheckedItem(R.id.nav_firstTable);
        binding.navView.setNavigationItemSelectedListener(item -> {
            int id = item.getItemId();
            if (id == R.id.nav_firstTable) {
                // “我的课表”
                setTable(1);
                initCourseTable();
            } else if (id == R.id.nav_secondTable) {
                // “第二课表”
                setTable(2);
                initCourseTable();
            } else if (id == R.id.nav_musicMode) {
                // 音乐模式
                initMusic();
            } else if (id == R.id.nav_score) {
                // 成绩查询
                showScoreQueryDialog();
            } else if (id == R.id.nav_exam) {
                // 考试安排
                showExamQueryDialog();
            } else if (id == R.id.nav_setting) {
                // 设置
                showSettingDialog();
            }
            binding.drawerLayout.closeDrawers();
            return true;
        });

        binding.lastWeek.setOnClickListener(view -> {
            if (binding.week.isClickable()) {
                // 上一周
                viewModel.weekMinusOne();
            } else {
                // 上一个乐器
                PreferencesDao.saveMidiNum(MusicUtils.lastMidiNum(PreferencesDao.getMidiNum()));
                binding.week.setText(MusicUtils.midi(PreferencesDao.getMidiNum()));
            }
        });

        binding.nextWeek.setOnClickListener(view -> {
            if (binding.week.isClickable()) {
                // 下一周
                viewModel.weekPlusOne();
            } else {
                // 下一个乐器号
                PreferencesDao.saveMidiNum(MusicUtils.nextMidiNum(PreferencesDao.getMidiNum()));
                binding.week.setText(MusicUtils.midi(PreferencesDao.getMidiNum()));
            }
        });

        binding.week.setOnClickListener(view -> {
            // 回到本周
            viewModel.resetWeek();
        });

        binding.cutTable.setOnClickListener(view -> {
            // 切换周视图/日视图
            setCourseView(!viewModel.isWeekView);
        });

        binding.tableName.setOnClickListener(view -> {
            // 显示课程导入菜单
            showImportMenu();
        });
    }

    @Override
    protected void onStop() {
        Log.d("MainActivity", "onStop");
        super.onStop();
        // 保存视图设置
        PreferencesDao.saveIsWeekView(viewModel.isWeekView);
    }

    @Override
    protected void onDestroy() {
        Log.d("MainActivity", "onDestroy");
        super.onDestroy();
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            binding.drawerLayout.openDrawer(GravityCompat.START);
        }
        return true;
    }

    /**
     * 初始化课表模式
     */
    private void initCourseTable() {
        // 当不是课表模式时才初始化
        if (!binding.tableName.isClickable()) {
            if (viewModel.isWeekView) {
                replaceFragment(weekFragment);
            } else {
                replaceFragment(dayFragment);
            }
            viewModel.updateTableName();
            Integer week = viewModel.getWeek().getValue();
            if (week != null) {
                binding.week.setText("第" + week + "周");
            }
            binding.tableName.setClickable(true);
            binding.week.setClickable(true);
            binding.cutTable.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 初始化音乐模式
     */
    private void initMusic() {
        // 当不是音乐模式时才初始化
        if (binding.tableName.isClickable()) {
            binding.tableName.setText("Music");
            binding.week.setText(MusicUtils.midi(PreferencesDao.getMidiNum()));
            binding.tableName.setClickable(false);
            binding.week.setClickable(false);
            binding.cutTable.setVisibility(View.INVISIBLE);
            replaceFragment(musicFragment);
        }
    }

    /**
     * 更新课程表
     *
     * @param resetWeek 是否重置周次
     */
    private void updateCourseTable(boolean resetWeek) {
        Integer week = viewModel.getWeek().getValue();
        if (resetWeek || week == null) {
            viewModel.resetWeek();
        }
        if (week != null) {
            weekFragment.updateCourses(viewModel.tableId, week);
        }
        dayFragment.updateCourses(viewModel.tableId);
        viewModel.updateTableName();
    }

    /**
     * 设置课表
     *
     * @param tableId 课表编号
     */
    private void setTable(int tableId) {
        if (tableId != viewModel.tableId) {
            viewModel.tableId = tableId;
            updateCourseTable(false);
        }
    }

    /**
     * 设置课程视图
     *
     * @param isWeeView 是否为周视图
     */
    private void setCourseView(boolean isWeeView) {
        viewModel.isWeekView = isWeeView;
        if (isWeeView) {
            replaceFragment(weekFragment);
            binding.week.setClickable(true);
            binding.lastWeek.setVisibility(View.VISIBLE);
            binding.nextWeek.setVisibility(View.VISIBLE);
            binding.cutTable.setText("当天课表");
        } else {
            replaceFragment(dayFragment);
            // 日视图禁止切换周次
            binding.week.setClickable(false);
            binding.lastWeek.setVisibility(View.INVISIBLE);
            binding.nextWeek.setVisibility(View.INVISIBLE);
            binding.cutTable.setText("周课表");
            // 重置周次为当前周
            viewModel.resetWeek();
        }
    }

    /**
     * 弹出导入菜单
     */
    private void showImportMenu() {
        BottomDialogBinding dialogBinding = BottomDialogBinding.inflate(getLayoutInflater());
        LinearLayout root = dialogBinding.getRoot();
        Dialog importMenu = new Dialog(this, R.style.BottomDialog);
        importMenu.setContentView(root);
        dialogBinding.personalCourse.setOnClickListener(view -> {
            showPersonalImportDialog();
            importMenu.dismiss();
        });
        dialogBinding.classCourse.setOnClickListener(view -> {
            showClassImportDialog();
            importMenu.dismiss();
        });
        dialogBinding.teacherCourse.setOnClickListener(view -> {
            showTeacherImportDialog();
            importMenu.dismiss();
        });
        Window dialogWindow = importMenu.getWindow();
        dialogWindow.setGravity(Gravity.BOTTOM);
//        dialogWindow.setWindowAnimations(R.style.DialogAnimation); // 添加动画
        WindowManager.LayoutParams lp = dialogWindow.getAttributes(); // 获取对话框当前的参数值
        lp.x = 0; // 新位置X坐标
        lp.y = 0; // 新位置Y坐标
        lp.width = (int) getResources().getDisplayMetrics().widthPixels; // 宽度
        root.measure(0, 0);
        lp.height = root.getMeasuredHeight();
        lp.alpha = 9f; // 透明度
        dialogWindow.setAttributes(lp);
        importMenu.show();
    }

    /**
     * 显示个人课表导入框
     */
    private void showPersonalImportDialog() {
        UserinfoInputDialogBinding dialogBinding = UserinfoInputDialogBinding.inflate(getLayoutInflater());
        AlertDialog importDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        dialogBinding.hint.setText(viewModel.tableId == 1 ? "我的课表" : "第二课表");
        dialogBinding.confirm.setText("导入");
        dialogBinding.confirm.setOnClickListener(view -> {
            hideKeyBoard(view);
            // 点击 ”导入“ 后弹出框无法关闭
            importDialog.setCancelable(false);
            // 点击一次之后不可点击
            dialogBinding.confirm.setClickable(false);
            dialogBinding.progressBar.setVisibility(View.VISIBLE);
            String username = dialogBinding.username.getText().toString().trim();
            String password = dialogBinding.password.getText().toString().trim();
            if ("".equals(username) || "".equals(password)) {
                Toast.makeText(this, "导入失败", Toast.LENGTH_SHORT).show();
                importDialog.dismiss();
                return;
            }
            new Thread(() -> {
                if (!Repository.importPersonalCourse(viewModel.tableId, username, password)) {
                    showToast("导入失败");
                    importDialog.dismiss();
                    return;
                }
                updateCourseTable(true);
                importDialog.dismiss();
                showToast("导入成功");
            }).start();
        });
        importDialog.show();
    }

    /**
     * 显示班级课表导入框
     */
    private void showClassImportDialog() {
        String username = PreferencesDao.getUsername();
        String password = PreferencesDao.getPassword();
        if (username == null) {
            Toast.makeText(this, "请先设置用户信息", Toast.LENGTH_SHORT).show();
            return;
        }
        ClassImportDialogBinding dialogBinding = ClassImportDialogBinding.inflate(getLayoutInflater());
        AlertDialog importDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        dialogBinding.tableName.setText(viewModel.tableId == 1 ? "我的课表" : "第二课表");
        dialogBinding.importTable.setOnClickListener(view -> {
            hideKeyBoard(view);
            // 点击 ”导入“ 后弹出框无法关闭
            importDialog.setCancelable(false);
            // 点击一次之后不可点击
            dialogBinding.importTable.setClickable(false);
            dialogBinding.importProgress.setVisibility(View.VISIBLE);
            String gradeStr = dialogBinding.grade.getText().toString().trim();
            String major = dialogBinding.major.getText().toString().trim();
            String classNumStr = dialogBinding.classNum.getText().toString().trim();
            if ("".equals(username) || "".equals(password) || "".equals(gradeStr) ||
                    "".equals(major) || "".equals(classNumStr)) {
                Toast.makeText(this, "导入失败：信息不完整", Toast.LENGTH_SHORT).show();
                importDialog.dismiss();
                return;
            }
            int classNum = Integer.parseInt(classNumStr);
            if (classNum <= 0) {
                Toast.makeText(this, "导入失败：班级不正确", Toast.LENGTH_SHORT).show();
                importDialog.dismiss();
                return;
            }
            new Thread(() -> {
                if (!Repository.importClassCourse(viewModel.tableId, username, password, Integer.parseInt(gradeStr), major, classNum)) {
                    showToast("导入失败");
                    importDialog.dismiss();
                    return;
                }
                updateCourseTable(true);
                importDialog.dismiss();
                showToast("导入成功");
            }).start();
        });
        importDialog.show();
    }

    /**
     * 显示教师课表导入框
     */
    private void showTeacherImportDialog() {
        String username = PreferencesDao.getUsername();
        String password = PreferencesDao.getPassword();
        if (username == null) {
            Toast.makeText(this, "请先设置用户信息", Toast.LENGTH_SHORT).show();
            return;
        }
        TeacharImportDialogBinding dialogBinding = TeacharImportDialogBinding.inflate(getLayoutInflater());
        AlertDialog importDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        dialogBinding.tableName.setText(viewModel.tableId == 1 ? "我的课表" : "第二课表");
        dialogBinding.importTable.setOnClickListener(view -> {
            hideKeyBoard(view);
            // 点击 ”导入“ 后弹出框无法关闭
            importDialog.setCancelable(false);
            // 点击一次之后不可点击
            dialogBinding.importTable.setClickable(false);
            dialogBinding.importProgress.setVisibility(View.VISIBLE);
            String teacherName = dialogBinding.teacherName.getText().toString().trim();
            if ("".equals(username) || "".equals(password) || "".equals(teacherName)) {
                Toast.makeText(this, "导入失败", Toast.LENGTH_SHORT).show();
                importDialog.dismiss();
                return;
            }
            new Thread(() -> {
                if (!Repository.importTeacherCourse(viewModel.tableId, username, password, teacherName)) {
                    showToast("导入失败");
                    importDialog.dismiss();
                    return;
                }
                updateCourseTable(true);
                importDialog.dismiss();
                showToast("导入成功");
            }).start();
        });
        importDialog.show();
    }

    /**
     * 显示用户信息设置框
     */
    private void showUserSetDialog() {
        UserSetDialogBinding dialogBinding = UserSetDialogBinding.inflate(getLayoutInflater());
        AlertDialog userSetDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        dialogBinding.save.setOnClickListener(view -> {
            hideKeyBoard(view);
            String username = dialogBinding.username.getText().toString().trim();
            String password = dialogBinding.password.getText().toString().trim();
            if ("".equals(username) || "".equals(password)) {
                Toast.makeText(this, "学号、密码不能为空", Toast.LENGTH_SHORT).show();
                userSetDialog.dismiss();
                return;
            }
            PreferencesDao.saveUserInfo(username, password);
            userSetDialog.dismiss();
            TextView nameText = binding.navView.getHeaderView(0).findViewById(R.id.username);
            nameText.setText(username);
            Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
        });
        userSetDialog.show();
    }

    /**
     * 显示成绩查询窗口
     */
    private void showScoreQueryDialog() {
        UserinfoInputDialogBinding dialogBinding = UserinfoInputDialogBinding.inflate(getLayoutInflater());
        AlertDialog queryDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        dialogBinding.hint.setText("成绩查询");
        dialogBinding.confirm.setText("查询");
        dialogBinding.confirm.setOnClickListener(view -> {
            hideKeyBoard(view);
            // 点击 ”查询“ 后窗口无法关闭
            queryDialog.setCancelable(false);
            // 点击一次之后不可点击
            dialogBinding.confirm.setClickable(false);
            dialogBinding.progressBar.setVisibility(View.VISIBLE);
            String username = dialogBinding.username.getText().toString().trim();
            String password = dialogBinding.password.getText().toString().trim();
            if ("".equals(username) || "".equals(password)) {
                Toast.makeText(this, "学号、密码不能为空", Toast.LENGTH_SHORT).show();
                queryDialog.dismiss();
                return;
            }
            new Thread(() -> {
                List<Score> scores = Repository.getScores(username, password);
                if (scores == null) {
                    showToast("查询失败");
                    queryDialog.dismiss();
                    return;
                }
                queryDialog.dismiss();
                runOnUiThread(() -> showScoreDialog(scores));
            }).start();
        });
        queryDialog.show();
    }

    /**
     * 显示考试查询窗口
     */
    private void showExamQueryDialog() {
        UserinfoInputDialogBinding dialogBinding = UserinfoInputDialogBinding.inflate(getLayoutInflater());
        AlertDialog queryDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        dialogBinding.hint.setText("考试查询");
        dialogBinding.confirm.setText("查询");
        dialogBinding.confirm.setOnClickListener(view -> {
            hideKeyBoard(view);
            // 点击 ”查询“ 后窗口无法关闭
            queryDialog.setCancelable(false);
            // 点击一次之后不可点击
            dialogBinding.confirm.setClickable(false);
            dialogBinding.progressBar.setVisibility(View.VISIBLE);
            String username = dialogBinding.username.getText().toString().trim();
            String password = dialogBinding.password.getText().toString().trim();
            if ("".equals(username) || "".equals(password)) {
                Toast.makeText(this, "学号、密码不能为空", Toast.LENGTH_SHORT).show();
                queryDialog.dismiss();
                return;
            }
            new Thread(() -> {
                List<Exam> exams = Repository.getExams(username, password);
                if (exams == null) {
                    showToast("查询失败");
                    queryDialog.dismiss();
                    return;
                }
                queryDialog.dismiss();
                runOnUiThread(() -> showExamDialog(exams));
            }).start();
        });
        queryDialog.show();
    }

    /**
     * 显示成绩窗口
     */
    private void showScoreDialog(@NonNull List<Score> scores) {
        ScoreDialogBinding dialogBinding = ScoreDialogBinding.inflate(getLayoutInflater());
        AlertDialog scoreDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        dialogBinding.scoreList.setLayoutManager(layoutManager);
        ScoreAdapter scoreAdapter = new ScoreAdapter(scores);
        dialogBinding.scoreList.setAdapter(scoreAdapter);
        scoreDialog.show();
    }

    /**
     * 显示考试安排窗口
     */
    private void showExamDialog(@NonNull List<Exam> exams) {
        ExamDialogBinding dialogBinding = ExamDialogBinding.inflate(getLayoutInflater());
        AlertDialog examDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        dialogBinding.examList.setLayoutManager(layoutManager);
        ExamAdapter examAdapter = new ExamAdapter(exams);
        dialogBinding.examList.setAdapter(examAdapter);
        examDialog.show();
    }

    /**
     * 显示设置窗口
     */
    private void showSettingDialog() {
        SettingDialogBinding dialogBinding = SettingDialogBinding.inflate(getLayoutInflater());
        AlertDialog settingDialog = new AlertDialog.Builder(this)
                .setView(dialogBinding.getRoot())
                .create();
        // 设置开关按钮的初始状态
        dialogBinding.examRemind.setChecked(PreferencesDao.examMonitoring());
        dialogBinding.scoreRemind.setChecked(PreferencesDao.scoreMonitoring());
        dialogBinding.examRemind.setOnCheckedChangeListener((button, checked) -> {
            if (checked) {
                String username = PreferencesDao.getUsername();
                if (username == null) {
                    dialogBinding.examRemind.setChecked(false);
                    Toast.makeText(this, "请先设置用户信息", Toast.LENGTH_SHORT).show();
                    return;
                }
                // 开启考试安排监控
                new Thread(() -> {
                    // 保存初始考试安排记录数
                    List<Exam> exams = Repository.getExams(PreferencesDao.getUsername(),
                            PreferencesDao.getPassword());
                    if (exams == null) {
                        runOnUiThread(() -> {
                            dialogBinding.examRemind.setChecked(false);
                            Toast.makeText(this, "考试安排监控开启失败：无法获取考试安排",
                                    Toast.LENGTH_SHORT).show();
                        });
                        return;
                    }
                    PreferencesDao.saveExamCount(exams.size());
                    // 开启定时任务
                    PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(ExamMonitorWorker.class, 1, TimeUnit.DAYS)
//                    PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(ExamMonitorWorker.class, 15, TimeUnit.MINUTES)
                            .addTag("examMonitor")
                            .build();
                    WorkManager.getInstance(this).enqueue(request);
                }).start();
            } else {
                // 关闭考试安排监控
                WorkManager.getInstance(this).cancelAllWorkByTag("examMonitor");
            }
            // 保存考试安排监控状态
            PreferencesDao.saveExamMonitorState(dialogBinding.examRemind.isChecked());
        });
        dialogBinding.scoreRemind.setOnCheckedChangeListener((button, checked) -> {
            if (checked) {
                String username = PreferencesDao.getUsername();
                if (username == null) {
                    dialogBinding.scoreRemind.setChecked(false);
                    Toast.makeText(this, "请先设置用户信息", Toast.LENGTH_SHORT).show();
                    return;
                }
                // 开启成绩监控
                new Thread(() -> {
                    // 保存初始成绩记录数
                    List<Score> scores = Repository.getScores(PreferencesDao.getUsername(),
                            PreferencesDao.getPassword());
                    if (scores == null) {
                        runOnUiThread(() -> {
                            dialogBinding.scoreRemind.setChecked(false);
                            Toast.makeText(this, "成绩监控开启失败：无法获取成绩",
                                    Toast.LENGTH_SHORT).show();
                        });
                        return;
                    }
                    PreferencesDao.saveScoreCount(scores.size());
                    // 开启定时任务
                    PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(ScoreMonitorWorker.class, 1, TimeUnit.DAYS)
//                    PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(ScoreMonitorWorker.class, 15, TimeUnit.MINUTES)
                            .addTag("scoreMonitor")
                            .build();
                    WorkManager.getInstance(this).enqueue(request);
                }).start();
            } else {
                // 关闭成绩监控
                WorkManager.getInstance(this).cancelAllWorkByTag("scoreMonitor");
            }
            // 保存成绩监控状态
            PreferencesDao.saveScoreMonitorState(dialogBinding.scoreRemind.isChecked());
        });
        settingDialog.show();
    }

    /**
     * 播放音乐
     *
     * @param name 音乐文件名（带后缀）
     */
    public void playMusic(String name) {
        try {
            AssetFileDescriptor fd = getAssets().openFd(name);
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
            mediaPlayer.prepare();
            mediaPlayer.start();
            new Handler().postDelayed(() -> {
                mediaPlayer.stop();
                mediaPlayer.reset();
                mediaPlayer.release();
            }, 2000);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 切换 fragment
     */
    private void replaceFragment(Fragment fragment) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.add_container, fragment).commit();
    }

    /**
     * 收起键盘
     */
    private void hideKeyBoard(View view) {
        InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (manager != null) {
            manager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    /**
     * 显示 Toast 消息（子线程用）
     *
     * @param text 内容
     */
    private void showToast(String text) {
        runOnUiThread(() -> {
            Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
        });
    }
}